
// il - A image library representation.

// Copyright (C) 2005-2006 VM Inc.
// Released under the LGPL.
// For more information, see http://www.openlibraries.org.

#ifndef RGB_TRAITS_INC_
#define RGB_TRAITS_INC_

namespace olib { namespace openimagelib { namespace il {

//
template<typename T, class storage = default_storage<T> >
class b8g8r8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;

private:
	static const int bs = 3;

public:
	explicit b8g8r8( size_type width, 
					 size_type height, 
					 size_type depth, 
					 size_type count		= 1, 
					 bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"b8g8r8" )
	{ surface_format<T, storage>::allocate( ); }

	b8g8r8( const b8g8r8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"b8g8r8" )
	{ surface_format<T, storage>::allocate( ); }

	virtual ~b8g8r8( )
	{ }

public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual b8g8r8* clone( size_type w, size_type h )
	{ return new b8g8r8( *this, w, h ); }
};

//
template<typename T, class storage = default_storage<T> >
class r8g8b8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;

private:
	static const int bs = 3;

public:
	explicit r8g8b8( size_type width, 
					 size_type height, 
					 size_type depth, 
					 size_type count		= 1, 
					 bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"r8g8b8" )
	{ surface_format<T, storage>::allocate( ); }

	r8g8b8( const r8g8b8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"r8g8b8" )
	{ surface_format<T, storage>::allocate( ); }

	virtual ~r8g8b8( )
	{ }

public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual r8g8b8* clone( size_type w, size_type h )
	{ return new r8g8b8( *this, w, h ); }
};

//
template<typename T, class storage = default_storage<T> >
class b8g8r8a8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;

private:
	static const int bs = 4;

public:
	explicit b8g8r8a8( size_type width, 
					   size_type height, 
					   size_type depth, 
					   size_type count		= 1, 
					   bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"b8g8r8a8" )
	{ surface_format<T, storage>::allocate( ); }

	b8g8r8a8( const b8g8r8a8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"b8g8r8a8" )
	{ surface_format<T, storage>::allocate( ); }
		
	virtual ~b8g8r8a8( )
	{ }
	
public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual b8g8r8a8* clone( size_type w, size_type h )
	{ return new b8g8r8a8( *this, w, h ); }
};

//
template<typename T, class storage = default_storage<T> >
class a8b8g8r8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;

private:
	static const int bs = 4;

public:
	explicit a8b8g8r8( size_type width, 
					   size_type height, 
					   size_type depth, 
					   size_type count		= 1, 
					   bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"a8b8g8r8" )
	{ surface_format<T, storage>::allocate( ); }

	a8b8g8r8( const a8b8g8r8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"a8b8g8r8" )
	{ surface_format<T, storage>::allocate( ); }
		
	virtual ~a8b8g8r8( )
	{ }
	
public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual a8b8g8r8* clone( size_type w, size_type h )
	{ return new a8b8g8r8( *this, w, h ); }
};

template<typename T, class storage = default_storage<T> >
class r8g8b8a8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;

private:
	static const int bs = 4;

public:
	explicit r8g8b8a8( size_type width, 
					   size_type height, 
					   size_type depth, 
					   size_type count		= 1, 
					   bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"r8g8b8a8" )
	{ surface_format<T, storage>::allocate( ); }

	r8g8b8a8( const r8g8b8a8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"r8g8b8a8" )
	{ surface_format<T, storage>::allocate( ); }
		
	virtual ~r8g8b8a8( )
	{ }
	
public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual r8g8b8a8* clone( size_type w, size_type h )
	{ return new r8g8b8a8( *this, w, h ); }
};

//
// surface format to represent L8 format.
//
template<typename T, class storage = default_storage<T> >
class l8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;
	
private:
	static const int bs = 1;
		
public:
	explicit l8( size_type width,
				 size_type height,
				 size_type depth,
				 size_type count		= 1,
				 bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"l8" )
	{ surface_format<T, storage>::allocate( ); }

	l8( const l8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"l8" )
	{ surface_format<T, storage>::allocate( ); }
		
	virtual ~l8( )
	{ }
	
public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual l8* clone( size_type w, size_type h )
	{ return new l8( *this, w, h ); }
};

//
// surface format to represent L8A8 format.
//
template<typename T, class storage = default_storage<T> >
class l8a8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;
	
private:
	static const int bs = 2;
		
public:
	explicit l8a8( size_type width,
				   size_type height,
				   size_type depth,
				   size_type count		= 1,
				   bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"l8a8" )
	{ surface_format<T, storage>::allocate( ); }

	l8a8( const l8a8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"l8a8" )
	{ surface_format<T, storage>::allocate( ); }
		
	virtual ~l8a8( )
	{ }
	
public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual l8a8* clone( size_type w, size_type h )
	{ return new l8a8( *this, w, h ); }
};

//
template<typename T, class storage = default_storage<T> >
class a8r8g8b8 : public surface_format<T, storage>
{
public:
	typedef typename storage::const_pointer					const_pointer;
	typedef typename storage::pointer						pointer;
	typedef typename surface_format<T, storage>::size_type	size_type;

private:
	static const int bs = 4;

public:
	explicit a8r8g8b8( size_type width, 
					   size_type height, 
					   size_type depth, 
					   size_type count		= 1, 
					   bool cubemap			= false )
		: surface_format<T, storage>( bs, width, height, depth, count, cubemap, L"a8r8g8b8" )
	{ surface_format<T, storage>::allocate( ); }

	a8r8g8b8( const a8r8g8b8& other, size_type w, size_type h )
		: surface_format<T, storage>( other.bs, w, h, other.depth( ), other.count( ), other.is_cubemap( ), L"a8r8g8b8" )
	{ surface_format<T, storage>::allocate( ); }

	virtual ~a8r8g8b8( )
	{ }

public:
	virtual size_type allocsize( size_type width, size_type height, size_type depth ) const
	{ return detail::rgb_Allocate_size<T>( )( bs, width, height, depth ); }
	
	virtual a8r8g8b8* clone( size_type w, size_type h )
	{ return new a8r8g8b8( *this, w, h ); }
};

} } }

#endif


